package com.cnpinxi.tool;

import com.cnpinxi.domain.abstraction.AbstractListable;
import com.cnpinxi.tool.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Andrew  on 2017/1/11.
 */
public class WriteToExcelFile {
    public static final String tempPath;
    static {
        tempPath= System.getProperty("webapp.root")+"excel/";
        File file=new File(tempPath);
        if (!file.isDirectory()){
            file.mkdirs();
            System.out.println("创建临时目录");
        }else {
            System.out.println("临时目录存在");
        }
    }
    /**
     *
     * @param fileName excel文件名
     * @param list 需要输出的数据
     * @param <T>list类型必须继承Listable,并且第一个元素必须设置父类信息
     * @throws Exception
     */
    public static<T extends AbstractListable> void writeToFile(String fileName, List<T> list) throws Exception{
        String[]fieldNames;
        String[]fieldAlias;

        //设置excel列名
        if (list==null){
            return;
        }else {
            fieldNames=list.get(0).getFieldName();
            //若果输出l列名为空
            if (fieldNames==null){
                Field[]fields=list.get(0).getClass().getDeclaredFields();

                for (int i=0;i<fields.length;i++) {
                    fieldNames[i]=fields[i].getName();
                }
            }
            fieldAlias=list.get(0).getFieldAlias();
            if (fieldAlias==null||fieldNames.length!=fieldAlias.length){
                fieldAlias=fieldNames;
            }
        }

        //判断文件类型
        Workbook workbook=createWorkbook(fileName);

        //创建表格以及填充数据
        Sheet sheet = workbook.createSheet("sheet1");
        setOneRow(sheet,0,fieldAlias);
        Class type=list.get(0).getClass();
        for (int i=0;i<list.size();i++){
            Row row = sheet.createRow(i+1);
            for (int j=0;j<fieldNames.length;j++) {
                Field field=type.getDeclaredField(fieldNames[j]);
                Cell cell=row.createCell(j);
                field.setAccessible(true);
//                cell.setCellValue();
                /**
                 *
                 * 处理金额，int转double
                 *
                 */
                if (field.getType()== Date.class){
                    cell.setCellValue(com.cnpinxi.tool.DateFormat.DateToString((Date) field.get(list.get(i))));
                }else {
                    cell.setCellValue(field.get(list.get(i)).toString());
                }
            }
        }

        //输出到文件
        FileOutputStream fos = new FileOutputStream(new File(tempPath,fileName));
        workbook.write(fos);
        fos.close();
        System.out.println(fileName + " written successfully");
    }

    public static<T> Map<String,Object> writeToFile(String fileName, String[]fieldNames, String[]fieldAlias, List<Map<String,T>> list){
        Map<String,Object>result=new HashMap<>();
        if (fieldAlias==null){
            fieldAlias=fieldNames;
        }
        Workbook workbook = null;
        try {
            workbook = createWorkbook(fileName);
        } catch (Exception e) {
            result.put("result",0);
            result.put("season","创建excel文件失败");
            e.printStackTrace();
            return result;
        }
        Sheet sheet = workbook.createSheet("sheet1");
        setOneRow(sheet,0,fieldAlias);
        for (int i=0;i<list.size();i++) {
            Row row = sheet.createRow(i + 1);
            for (int j = 0; j < fieldNames.length; j++) {
                Cell cell = row.createCell(j);
//                cell.setCellValue();
                /**
                 *
                 * 处理金额，int转double
                 *
                 */
                Class type=list.get(i).get(fieldNames[j]).getClass();
                System.out.println(type.getName());
                if (type== Date.class||type== Timestamp.class) {
                    cell.setCellValue(com.cnpinxi.tool.DateFormat.DateToString((Date) list.get(i).get(fieldNames[j])));
                }else if (type == Double.class||type == double.class||type == Integer.class||type == int.class){
                    cell.setCellValue(Double.valueOf(list.get(i).get(fieldNames[j]).toString()));
                }else {
                    cell.setCellValue(list.get(i).get(fieldNames[j]).toString());
                }
            }
        }
        //输出到文件
        try(FileOutputStream fos = new FileOutputStream(new File(tempPath,fileName))) {
            workbook.write(fos);
        }catch (IOException e){
            e.printStackTrace();
            result.put("result",0);
            result.put("season","文件输出失败");
            return result;
        }
        result.put("result",1);
        result.put("path",tempPath+fileName);
        System.out.println(fileName + " written successfully");
        return result;
    }


    private static void setOneRow(Sheet sheet,int rowIndex,String[] values){
        Row row=sheet.createRow(rowIndex);
        for (int i=0;i<values.length;i++){
            Cell cell=row.createCell(i);
            cell.setCellValue(values[i]);
        }

    }
    private static Workbook createWorkbook(String fileName) throws Exception {
        Workbook workbook=null;
        //判断文件类型
        if(fileName.endsWith("xlsx")){
            //Excel2007以上
            workbook = new XSSFWorkbook();
        }else if(fileName.endsWith("xls")){
            workbook = new HSSFWorkbook();
        }else{
            throw new Exception("invalid file name, should be xls or xlsx");
        }
        return workbook;
    }
}
